﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web;
using System.Diagnostics;
using WebPattern.Core.Security;
using WebPattern.MVC.Resources.Views.Shared;

namespace WebPattern.MVC.Handler
{
    public class WebPatternHandlerErrorAttribute : HandleErrorAttribute
    {
        private bool Enabled { set; get; }
        public string  View { get; set; }

        public WebPatternHandlerErrorAttribute(bool enable)
            : base()
        {
            this.Enabled = enable;
        }
        public WebPatternHandlerErrorAttribute()
            : base()
        {
            this.Enabled = true;
        }

        //// Summary:
        ////     Gets or sets the type of the exception.
        ////
        //// Returns:
        ////     The type of the exception.
        //public Type ExceptionType { get; set; }
        ////
        //// Summary:
        ////     Gets or sets the master view for displaying exception information.
        ////
        //// Returns:
        ////     The master view.
        //public string Master { get; set; }
        ////
        //// Summary:
        ////     Gets the unique identifier for this attribute.
        ////
        //// Returns:
        ////     The unique identifier for this attribute.
        //public override object TypeId { get; }
        //
        // Summary:
        //     Gets or sets the page view for displaying exception information.
        //
        // Returns:
        //     The page view.
        

        // Summary:
        //     Called when an exception occurs.
        //
        // Parameters:
        //   filterContext:
        //     The action-filter context.
        //
        // Exceptions:
        //   System.ArgumentNullException:
        //     The filterContext parameter is null.
        public override void OnException(ExceptionContext filterContext)
        {
            if (!this.Enabled) return;
            
            base.OnException(filterContext);
            
            Debug.WriteLine("------------------    ERROR    --------------------");
            Debug.WriteLine("Exception Type: " + filterContext.Exception.GetType().ToString());
            Debug.WriteLine("Exception Message: " + filterContext.Exception.Message);
            Debug.WriteLine("---------------------------------------------------");

            if (filterContext.ExceptionHandled)
                RaiseErrorSignal(filterContext.Exception);

            #region Create ViewResult
            if (filterContext.HttpContext.User.IsInRole(AppRoles.Sysadmin.ToString()))
            {
                // SysAdmin mode :
                View = "ErrorAdmins";

                ((ViewResult)(filterContext.Result)).ViewBag.ShowElmah = "True";
                ((ViewResult)(filterContext.Result)).ViewBag.ExMessage = filterContext.Exception.Message;
                ((ViewResult)(filterContext.Result)).ViewBag.ExData = filterContext.Exception.Data.ToString();
                ((ViewResult)(filterContext.Result)).ViewBag.ExSource = filterContext.Exception.Source;
                ((ViewResult)(filterContext.Result)).ViewBag.ExStackTrace = filterContext.Exception.StackTrace;
                ((ViewResult)(filterContext.Result)).ViewBag.ExTargetSite = filterContext.Exception.TargetSite.ToString();
            }
            else
            {
                // NotSysAdmin mode :
                View = "Error";

                ((ViewResult)(filterContext.Result)).ViewBag.ExMessage = GetErrorMessage(filterContext);
            }

            ((ViewResult)(filterContext.Result)).ViewBag.Title = ErrorAll.Title;
            ((ViewResult)(filterContext.Result)).ViewBag.ExTitle = ErrorAll.DefaultErrorTtile;
            ((ViewResult)(filterContext.Result)).ViewName = View;
            #endregion
        }


        #region Helper Methods
        private static void RaiseErrorSignal(Exception e)
        {
            var context = HttpContext.Current;
            Elmah.ErrorSignal.FromContext(context).Raise(e, context);
        }

        private string GetErrorMessage(ExceptionContext filterContext)
        {
            string _message = string.Empty;
            int HTTPStatusCode;

            if (filterContext == null)
            {
                //System.ArgumentNullException
                _message = ErrorAll.DefaultErrorMessage;
            }
            else if (filterContext.HttpContext == null || filterContext.HttpContext.Response == null)
            {
                _message = ErrorAll.DefaultErrorMessage;
            }
            else
            {
                HTTPStatusCode = (filterContext.HttpContext.Response).StatusCode;

                // Set Messasge
                switch (HTTPStatusCode)
                {
                    case 500:
                        // server error
                        _message = ErrorAll.HTTPStatusCode500;
                        break;
                    // .....
                    //case XXX:
                    //    // XXX error
                    //    _message = ErrorAll.HTTPStatusCodeXXX;
                    //    break;
                    // .....
                    default:
                        _message = ErrorAll.DefaultErrorMessage;
                        break;
                } 
            }

            return _message;
        }
        #endregion
    }
}
